<?php

namespace App\Command\ResumeParsing\Service\ParsingSpecial;

use App\Service\FileHandler;
use EchoPHP\Facades\Log;

class ParsingZhilian extends ParsingSpecialXml {
    protected function onParsed() {
        parent::onParsed();
        $tmp = $this->xPath->query("//body/p[normalize-space()='聊聊列表']/preceding-sibling::*[1]/following-sibling::*");    //剪除多余信息
        foreach ($tmp as $node) {
            $node->parentNode->removeChild($node);
        }
    }

    function __construct($helper) {
        parent::__construct($helper);
        $this->titleXpath = "//body/p[ppr/rpr/sz[@*[local-name()='w:val' and .=27]] or normalize-space()='项目经验']";

        $this->get['template'] = function () {
            $this->listXPath("//templateTag[normalize-space()='templateTagName']");    //[contains(., 'templateTagName')][starts-with(normalize-space(), 'templateTagName')]
            $result = $this->xPath->query();
            if ($result->length < 1) return '';
            return $this->formatTxt($result[0]->textContent);
        };

        $this->get['id'] = function () {
            //$this->listXPath("//body/p[starts-with(normalize-space(), '简历') and contains(., 'ID') and contains(., '：')]");
            $result = $this->xPath->query("//body/p[starts-with(normalize-space(), '简历') and contains(., 'ID') and contains(., '：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:简历\s*ID\s*：)\s*(?<result>.*?)\s*(?=$)/u', $result[0]->textContent, array('groupName' => 'result'));
        };

        $this->get['time'] = function () {
            //$this->listXPath("//body/p[starts-with(normalize-space(), '最近活跃时间：')]");
            $result = $this->xPath->query("//body/p[starts-with(normalize-space(), '最近活跃时间：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?<=最近活跃时间：)\s*(?<result>.*?)\s*(?=$)/u', $result[0]->textContent, array('groupName' => 'result'));
        };

        $this->get['name'] = function () {
            //$this->listXPath("//p[(r/rpr/sz[@*[local-name()='w:val' and .>'30']] and string-length(normalize-space()) < 4 or contains(following-sibling::p[1], '男') or contains(following-sibling::p[1], '女') or contains(following-sibling::p[1], '年')) and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]]");
            $result = $this->xPath->query("//p[(r/rpr/sz[@*[local-name()='w:val' and .>'30']] and string-length(normalize-space()) < 4 or contains(following-sibling::p[1], '男') or contains(following-sibling::p[1], '女') or contains(following-sibling::p[1], '年')) and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]][1]");
            if ($result->length < 1) return '';
            return $this->formatTxt($result[0]->textContent);
        };

        $this->groupGetter['basic'] = array();

        $this->groupGetter['basic'][0] = function () {
            //$this->listXPath("//p[contains(., '男') or contains(., '女') or contains(., '年') and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]][1]");
            $result = $this->xPath->query("//p[contains(., '男') or contains(., '女') or contains(., '年') and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]][1]");
            if ($result->length < 1) return '';
            return preg_split('/\s*\|\s*/u', $this->formatTxt($result[0]->textContent, TRUE));
        };

        $this->groupGetter['basic'][] = function ($text) {
            if (preg_match('/^[男女]$/u', $text)) {
                return array('sex' => $text);
            }
        };

        $this->groupGetter['basic'][] = function ($text) {
            if (preg_match('/^(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?$/u', $text)) {
                return array('birthday' => $text);
            }
        };

        $this->groupGetter['basic'][] = function ($text) {
            if (preg_match('/^\d{2}岁$/u', $text)) {
                return array('age' => $text);
            }
        };

        $this->groupGetter['basic'][] = function ($text) {
            $text = $this->formatTxt($text, TRUE);
            if (preg_match('/^(?:\d{1,2}\s*年(?:\s*[01]?\d\s*个?月)?|\d{1,2}\s*个?月)(?:\s*以上|\+)?(?=工作经验)/u', $text, $matches)) {
                return array('workyear' => $matches[0]);
            }
        };

        $this->groupGetter['basic'][] = function ($text) {
            static $dictDegree = array(
                "博士后" => 9,
                "博士" => 9,
                "MBA" => 8,
                "EMBA" => 8,
                "硕士" => 7,
                "本科" => 6,
                "大专" => 5,
                "中专" => 4,
                "中技" => 3,
                "中技" => 3,
                "高中" => 2,
                "中学" => 1,
                "初中" => 1,
                "初中以下" => 1,
                "初中及以下" => 1,
                "小学" => 1
            );
            if (isset($dictDegree[$text])) return array('degree' => $text);
        };

        $this->groupGetter['basic'][] = function ($text) {
            static $dictMarried = array("未婚" => 0, "已婚" => 0, "保密" => 2);
            if (isset($dictMarried[$text])) return array('married' => $text);
        };

        $this->get['sex'] = $this->groupGet('sex', 'basic');

        $this->get['nation'] = $this->tagNotExist;

        $this->get['identitycard'] = $this->tagNotExist;

        $this->get['mobile'] = function () {
            //$this->listXPath("//p[contains(., '手机') and (contains(., ':') or contains(., '：'))]");
            $result = $this->xPath->query("//p[contains(., '手机') and (contains(., ':') or contains(., '：'))]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:手机\s*[:：])\s*(?<result>.*?)\s*(?=\||$)/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 4));
        };

        $this->get['email'] = function () {
            //$this->listXPath("//p[contains(., '邮箱') and (contains(., ':') or contains(., '：'))]");
            $result = $this->xPath->query("//p[contains(., '邮箱') and (contains(., ':') or contains(., '：'))]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:邮箱\s*[:：])\s*(?<result>.*?)\s*(?=\||$)/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 4));
        };

        $this->get['age'] = $this->groupGet('age', 'basic');

        $this->get['married'] = $this->groupGet('married', 'basic');

        $this->get['politic'] = $this->tagNotExist;

        $this->get['degree'] = $this->groupGet('degree', 'basic');

        $this->get['industry'] = function () {
            //$this->listXPath("//p[starts-with(normalize-space(), '期望行业：')]");
            $result = $this->xPath->query("//p[starts-with(normalize-space(), '期望行业：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:期望行业：)\s*(?<result>.*?)\s*$/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 4));
        };

        $this->get['position'] = $this->tagNotExist;

        $this->get['career'] = function () {
            //$this->listXPath("//p[starts-with(normalize-space(), '期望从事职业：')]");
            $result = $this->xPath->query("//p[starts-with(normalize-space(), '期望从事职业：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:期望从事职业：)\s*(?<result>.*?)\s*$/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 4));
        };

        $this->get['major'] = $this->tagNotExist;

        $this->get['birthday'] = $this->groupGet('birthday', 'basic');

        $this->get['workyear'] = $this->groupGet('workyear', 'basic');

        $this->get['workarea'] = function () {
            //$this->listXPath("//p[contains(., '现居住地') and contains(., '：')]");
            $result = $this->xPath->query("//p[contains(., '现居住地') and contains(., '：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:现居住地\s*：)\s*(?<result>.*?)\s*(?=\||$)/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 3));
        };

        $this->get['expectarea'] = function () {
            //$this->listXPath("//p[starts-with(normalize-space(), '工作地点：')]");
            $result = $this->xPath->query("//p[starts-with(normalize-space(), '工作地点：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:工作地点：)\s*(?<result>.*?)\s*$/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 3));
        };

        $this->get['area'] = function () {
            //$this->listXPath("//p[contains(., '户口') and contains(., '：')]");
            $result = $this->xPath->query("//p[contains(., '户口') and contains(., '：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:户口\s*：)\s*(?<result>.*?)\s*(?=\||$)/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 3));
        };

        $this->get['salary'] = $this->tagNotExist;

        $this->get['expectsalary'] = function () {
            //$this->listXPath("//p[starts-with(normalize-space(), '期望薪资：')]");
            $result = $this->xPath->query("//p[starts-with(normalize-space(), '期望薪资：')]");
            if ($result->length < 1) return '';
            $resultText = $this->preg_get('/(?:期望薪资：)\s*(?<result>.*?)\s*$/u', $result[0]->textContent, array('groupName' => 'result', 'format' => 4));
            $expectsalary = $this->func->parseSalary($resultText);
            if (count($expectsalary)) {
                $this->helper->resumeInfo['expectsalaryfrom'] = $expectsalary['monthly']['begin'];
                $this->helper->resumeInfo['expectsalaryend'] = $expectsalary['monthly']['end'];
                //$this->helper->resumeInfo['expectsalaryafrom'] = $expectsalary['annual']['begin'];
                //$this->helper->resumeInfo['expectsalaryaend'] = $expectsalary['annual']['end'];
            }
            return $resultText;
        };

        $this->get['jobterm'] = function () {
            //$this->listXPath("//p[starts-with(normalize-space(), '期望工作性质：')]");
            $result = $this->xPath->query("//p[starts-with(normalize-space(), '期望工作性质：')]");
            if ($result->length < 1) return '';
            return $this->preg_get('/(?:期望工作性质：)\s*(?<result>.*?)\s*$/u', $result[0]->textContent);
        };

        $this->get['school'] = $this->tagNotExist;

        $this->get['nofocuse'] = $this->tagNotExist;

        $this->get['workinfo'] = function () {
            $result = $this->getPart('工作经验', true, 'p');
            $data = array();
            $trimCount = 0;
            foreach ($result as $node) {
                if (preg_match('/^(?<time>(?<!\d)(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:(?:\s*[-–—\/\\\\~到至]\s*)(?<!\d)(?:至今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))(?!\d))?)\s*(?<company>.+?)\s*(?:[(（](?<timespan>(?:\d{1,2}年(?:\s{0,2}[01]?\d个?月)?|\d{1,2}个?月)(?:以上|\+)?)[)）])?$/u', $this->formatTxt($node->textContent, TRUE), $matches)) {
                    if (isset($item)) {
                        $item['comment'] = trim($item['comment']);
                        $data[] = $item;
                    }
                    $trimCount = 0;
                    $time = $matches['time'];
                    $tmp = $this->func->parseTimespan($time);
                    $item = array('comment' => !empty($matches['timespan']) ? '工作时间：' . $matches['timespan'] : '', 'time' => $time, 'time_from' => $tmp['begin'], 'time_end' => $tmp['end'], 'company' => $matches['company']);
                } elseif (isset($item)) {
                    if (empty($item['duty']) && empty($item['salary'])) {
                        if (preg_match('/^(?<duty>.*?)\s*(?<salary>面议|保密|\d+(?:\.\d+)?\s*[kw万]?\s*元?(?:\s*[-–—~～至到]\s*(?:\d+(?:\.\d+)?\s*[kw万]?)\s*元?)?\s*[\/每].*?)(?:以上|以下)?$/u', $this->formatTxt($node->textContent, TRUE), $matches)) {
                            $item['duty'] = $matches['duty'];
                            $item['salary'] = $matches['salary'];
                        }
                    } elseif (empty($item['industry']) && ($industry = $this->preg_get('/^行业类别：\s*(?<result>.*)\s*$/u', $node->textContent))) {
                        $item['industry'] = $industry;
                    } else {
                        $text = $this->formatTxt($node->textContent);
                        if (!$trimCount) $text = preg_replace('/^工作描述\s*：\s*/u', '', $text, -1, $trimCount);
                        if (!empty($text)) $item['comment'] .= "\r\n" . $text;
                    }
                }
            }
            if (isset($item)) {
                $item['comment'] = trim($item['comment']);
                $data[] = $item;
            }
            return $data;
        };

        $this->get['projectinfo'] = function () {
            $result = $this->getPart('项目经验', true, 'p');
            $data = array();
            $trimCount0 = 0;
            $trimCount = 0;
            foreach ($result as $node) {
                if (preg_match('/^(?<time>(?<!\d)(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:(?:\s*[-–—\/\\\\~到至]\s*)(?<!\d)(?:至今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))(?!\d))?)\s*(?<project>.+?)$/u', $this->formatTxt($node->textContent), $matches)) {
                    if (isset($item)) {
                        $item['comment'] = trim($item['comment']);
                        $data[] = $item;
                    }
                    $trimCount0 = 0;
                    $trimCount = 0;
                    $time = $matches['time'];
                    $tmp = $this->func->parseTimespan($time);
                    $item = array('comment' => '', 'time' => $time, 'time_from' => $tmp['begin'], 'time_end' => $tmp['end'], 'project' => $matches['project']);
                } elseif (isset($item)) {
                    $text = $this->formatTxt($node->textContent);
                    if (!$trimCount0) $text = preg_replace('/^工作描述\s*：\s*/u', '', $text, -1, $trimCount0);
                    if (!$trimCount) $text = preg_replace('/^项目描述\s*：\s*/u', '', $text, -1, $trimCount);
                    if (!empty($text)) $item['comment'] .= "\r\n" . $text;
                }
            }
            if (isset($item)) {
                $item['comment'] = trim($item['comment']);
                $data[] = $item;
            }
            return $data;
        };

        $this->get['educationinfo'] = function () {
            //$this->listXPath("//p[normalize-space()='教育背景']/following-sibling::p", 4);
            $result = $this->getPart('教育背景', true, 'p');
            $data = array();
            foreach ($result as $node) {
                $text = $this->formatTxt($node->textContent, TRUE);
                if (preg_match('/^(?<time>(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:(?:\s*[-–—\/\\\\~～到至]\s*)(?<!\d)(?:至今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))))(?<school>.+?)\|(?<major>.+?)\|(?<degree>.+?)(?:\|(?<comment>.+))?$/u', $text, $matches)) {
                    $time = $matches['time'];
                    $tmp = $this->func->parseTimespan($time);
                    $data[] = array('comment' => $matches['comment'] ?? '', 'time' => $time, 'time_from' => $tmp['begin'], 'time_end' => $tmp['end'], 'school' => $matches['school'], 'major' => $matches['major'], 'degree' => $matches['degree'],);
                }
            }
            return $data;
        };

        $this->get['skillinfo'] = function () {
            $resultText = $this->getPart('专业技能');
            $part = $this->getPart('语言能力');
            if (!empty($part)) $resultText .= "\r\n" . $part;
            return trim($resultText);
        };

        $this->get['awardinfo'] = function () {
            return $this->getPart('获得证书');
        };

        $this->get['commentinfo'] = function () {
            return $this->getPart('自我评价');
        };

        $this->get['otherinfo'] = function () {
            $resultText = $this->groupCache['comment'];
            $part = $this->getPart('其他信息');
            if (!empty($part)) $resultText .= "\r\n" . $part;
            return trim($resultText);
        };

        $this->get['avatar'] = function () {
            try {
                //$this->listXPath("//p[(r/rpr/sz[@*[local-name()='w:val' and .>'30']] and string-length(normalize-space()) < 4 or contains(following-sibling::p[1], '男') or contains(following-sibling::p[1], '女') or contains(following-sibling::p[1], '年')) and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]][1]/preceding-sibling::p[1]//pic/blipfill/blip/@*[local-name()='r:embed']");
                if (!count($idNode = $this->xPath->query("//p[(r/rpr/sz[@*[local-name()='w:val' and .>'30']] and string-length(normalize-space()) < 4 or contains(following-sibling::p[1], '男') or contains(following-sibling::p[1], '女') or contains(following-sibling::p[1], '年')) and following-sibling::p[contains(normalize-space(), '最近活跃时间：')]][1]/preceding-sibling::p[1]//pic/blipfill/blip/@*[local-name()='r:embed']"))) return '';
                if (count($sourceNode = $this->xPath->query("../../preceding-sibling::nvpicpr[1]/cnvpr/@descr", $idNode[0]))
                    && preg_match('/\/resumeview\/head-[a-z-]*picture[a-z-]*\.jpg$/i', $url = $sourceNode[0]->textContent)) {  //默认头像
                    return '';
                }

                $imgInfo =& $this->helper->resume['resumeImage'][$idNode[0]->textContent];
                return ['data' => &$imgInfo['data'], 'name' => basename($url ?? $imgInfo['name'])];
            } catch (\Exception $e) {
                Log::error(e_dump($e), ['avatar' => $url ?? ''], 'cmd');
                return '';
            }
        };
    }
}
